package com.lebang.controller.api.member;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.lebang.common.util.QRCodeUtil;
import com.lebang.common.validcode.Maths;
import com.lebang.common.validcode.RedisLogin;
import com.lebang.common.validcode.ValidCodeStatus;
import com.lebang.common.validcode.ValidCodeUtil;
import com.lebang.component.RedisClient;
import com.lebang.entity.RequestHeaders;
import com.lebang.entity.member.LbbMember;
import com.lebang.entity.member.LbbMemberInviteNotice;
import com.lebang.entity.member.MemberInviteDetail;
import com.lebang.entity.member.TbMemberInviteStatistics;
import com.lebang.mapper.LbbMemberInviteNoticeMapper;
import com.lebang.mapper.buss.MemberInviteMapper;
import com.lebang.model.ValidCodeRecord;
import com.lebang.model.enums.Gender;
import com.lebang.service.MemberInviteRebateRecordService;
import com.lebang.service.MemberNoticeService;
import com.lebang.service.buss.*;
import com.lebang.service.setting.CashService;
import com.lebang.service.sys.DictService;
import com.lebangweb.common.DateUtil;
import com.lebangweb.common.TextUtil;
import com.lebangweb.common.UUIDUtil;
import com.lebangweb.encrypt.MessageDigestUtil;
import com.lebangweb.response.Callback;
import com.lebangweb.response.JsonData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;

import static com.lebang.common.validcode.RedisLock.LOCKPHONECODE;

/**
 * @author : tony
 * @Date: 2019-01-23 15:54
 * @Description: 针对于拉新的网页版的用户注册方法，标记的用户分类属性为：category：web，app：xianyu
 */
@RequestMapping("/invite")
@Controller
public class MemberInviteNewApi {

    @Autowired
    private ValidCodeService validCodeService;

    @Autowired
    private MemberInviteStatisticsService memberInviteStatisticsService;

    @Autowired
    private MemberInviteMapper memberInviteMapper;

    @Autowired
    private MemberService memberService;
    @Autowired
    private RedisClient redisClient;
    @Autowired
    private ValidCodeUtil validCodeUtil;
    @Autowired
    private LbbMemberInviteNoticeMapper memberInviteNoticeMapper;
    @Autowired
    private DictService dictService;
    @Autowired
    private MemberInviteRebateRecordService memberInviteRebateRecordService;
    @Autowired
    private MemberNoticeService memberNoticeService;
    @Autowired
    private CashService cashService;
    @Autowired
    private WalletService walletService;
    private static final Logger log = LoggerFactory.getLogger(MemberInviteNewApi.class);

    /**
     * 进入 注册 检测 页面
     *
     * @return
     */
    @RequestMapping(value = {"/check"}, method = {RequestMethod.GET})
    public String toCheck(HttpServletRequest request, HttpServletResponse response) {
        request.setAttribute("category", "web");
        request.setAttribute("app", "xianyu");
        return "/inviteNew/check";
    }


    /**
     * 进入 注册 页面
     *
     * @return
     */
    @RequestMapping(value = {"/register"}, method = {RequestMethod.GET})
    public String toRegister(HttpServletRequest request, HttpServletResponse response, String phone, String inviteCode) {
        request.setAttribute("category", "web");
        request.setAttribute("app", "xianyu");
        request.setAttribute("phone", phone);
        request.setAttribute("inviteCode", inviteCode);
        return "/inviteNew/register";
    }

    /**
     * 进入 规则 页面
     *
     * @return
     */
    @RequestMapping(value = {"/rule"}, method = {RequestMethod.GET})
    public String toRule() {
        return "/inviteNew/rule";
    }

    /**
     * 进入 下载 页面
     *
     * @return
     */
    @RequestMapping(value = {"/download"}, method = {RequestMethod.GET})
    public String toDownload(HttpServletRequest request, String phone, int type, String inviteCode) {
        request.setAttribute("phone", phone);
        request.setAttribute("inviteCode", inviteCode);
        if (type == 1) {
            request.setAttribute("title", "恭喜领取成功!");
        } else if (type == 2) {
            request.setAttribute("title", "<p>已经是老朋友了!</p><p>立即下载赚钱吧</p>");
        }
        return "/inviteNew/download";
    }

    /**
     * 进入 分享 页面
     *
     * @return
     */
    @RequestMapping(value = {"/sweep"}, method = {RequestMethod.GET})
    public String toSweep(HttpServletRequest request, String inviteCode) {
        request.setAttribute("inviteCode", inviteCode);
        return "/inviteNew/sweep";
    }


    @RequestMapping(value = "/qrcode", method = RequestMethod.GET)
    public void getQrImage(HttpServletResponse response, String inviteCode) throws IOException {
        String url = "http://newapi.hotbuybuy.com/invite/check";
        if (!TextUtil.isEmpty(inviteCode)) {
            url += "?inviteCode=" + inviteCode;
        }
        log.info(url);
        QRCodeUtil.createImage(url, "png", response.getOutputStream());
    }

    @RequestMapping(value = "/check/phone", method = RequestMethod.POST)
    @ResponseBody
    public JsonData getCheckPhone(HttpServletRequest request, HttpServletResponse response,
                                  @RequestParam(value = "category", required = false) String category,
                                  @RequestParam(value = "app", required = false) String app,
                                  @RequestParam(value = "inviteCode", required = false) String inviteCode,
                                  @RequestParam(value = "phone") String phone) {
        try {
            if (TextUtil.isEmpty(inviteCode)) {
                log.info("邀请码不存在，用户单独注册");
            }

            if (TextUtil.isEmpty(category, app) || !"web".equals(category) || !"xianyu".equals(app)) {
                return Callback.fail("403", "未知异常", "");
            }

            if (TextUtil.isEmpty(phone) || !TextUtil.isMobile(phone)) {
                log.info("用户手机号异常");
                return Callback.fail("403", "手机号异常", "");
            }

            //检测用户是否已经注册
            boolean isRegister = checkPhone(phone, app);
            if (!isRegister) {
                return Callback.fail("555", "手机号已被注册！", "");
            }
            return Callback.success("200", "可以注册！", "");

        } catch (Exception e) {
            e.printStackTrace();
        }
        return Callback.fail("403", "网络异常", "");
    }


    /**
     * 根据用户的手机号，获取验证码
     *
     * @param request
     * @param response
     * @param category   隐形的校验参数，标识是访问页面过来的
     * @param inviteCode 邀请码
     * @param phone      用户手机号/
     * @return
     */
    @RequestMapping(value = "/register/code", method = RequestMethod.POST)
    @ResponseBody
    public JsonData getRegisterByPhone(HttpServletRequest request, HttpServletResponse response,
                                       @RequestParam(value = "category", required = false) String category,
                                       @RequestParam(value = "app", required = false) String app,
                                       @RequestParam(value = "inviteCode", required = false) String inviteCode,
                                       @RequestParam(value = "phone") String phone) {
        try {
            if (TextUtil.isEmpty(inviteCode)) {
                log.info("邀请码不存在，用户单独注册");
            }

            if (TextUtil.isEmpty(category, app) || !"web".equals(category) || !"xianyu".equals(app)) {
                return Callback.fail("403", "未知异常", "");
            }

            if (TextUtil.isEmpty(phone) || !TextUtil.isMobile(phone)) {
                log.info("用户手机号异常");
                return Callback.fail("403", "手机号异常", "");
            }

            //检测用户是否已经注册
            boolean isRegister = checkPhone(phone, app);
            if (!isRegister) {
                return Callback.fail("555", "手机号已被注册！", "");
            }


            // 判断是今日是否已达上线
            synchronized (this) {
                int count = validCodeService.todayLimit("xianyu", phone, "Register");
                if (count >= 5) {
                    return Callback.fail("502", "今日注册次数已达上线！", "");
                }
            }
            //加锁防止重复发
            String uuid = UUIDUtil.M();
            boolean a = redisClient.tryGetDistributedLock(LOCKPHONECODE.getName() + phone, uuid, 3000);
            if (a) {

                ValidCodeStatus validCode = validCodeUtil.getValidCode(phone,new ValidCodeRecord(request));
                if (validCode.isStatus()) {
                    //验证码存入redis中
                    redisClient.setex(RedisLogin.PHONE_REGISTER_CODE.getName() + phone, 300, validCode.getCode());

                    return Callback.success("success", "发送成功", 90);
                } else {
                    return Callback.fail("fail", "发送失败" + validCode.getMsg(), null);
                }
            } else {
                return Callback.fail("fail", "请勿重复操作哦", null);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return Callback.fail("403", "未知异常", e.getMessage());
        }
    }


    /**
     * 根据用户填写的相关信息完成注册
     *
     * @param request
     * @param response
     * @param category   对应分类：web
     * @param app        对应应用：xianyu
     * @param inviteCode 邀请码
     * @param phone      手机号
     * @param code       验证码
     * @param password   密码
     * @return
     */
    @RequestMapping(value = "/register", method = RequestMethod.POST)
    @ResponseBody
    public JsonData registerByCode(HttpServletRequest request, HttpServletResponse response,
                                   @RequestParam(value = "category", required = false) String category,
                                   @RequestParam(value = "app", required = false) String app,
                                   @RequestParam(value = "inviteCode", required = false) String inviteCode,
                                   @RequestParam(value = "phone") String phone,
                                   @RequestParam(value = "code") String code,
                                   @RequestParam(value = "password") String password) {
        try {
            if (TextUtil.isEmpty(inviteCode)) {
                log.info("邀请码不存在，用户单独注册");
            }
            if (TextUtil.isEmpty(category, app) || !"web".equals(category) || !"xianyu".equals(app)) {
                return Callback.fail("403", "未知异常", "");
            }
            if (TextUtil.isEmpty(phone) || !TextUtil.isMobile(phone)) {
                log.info("用户手机号异常");
                return Callback.fail("403", "手机号异常", "");
            }
            if (TextUtil.isEmpty(code, password)) {
                log.info("验证码或者密码不能为空");
                return Callback.fail("403", "数据异常", "");
            }

            // 校验验证码
            if (!validCodeUtil.checkCode(phone, RedisLogin.PHONE_REGISTER_CODE, code)) {
                return Callback.fail("501", "验证码错误！", "");
            }


            // 判断手机号是否注册过
            boolean isRegister = checkPhone(phone, app);
            if (!isRegister) {
                return Callback.fail("555", "手机号已被注册！", "");
            }

            //生成邀请码并判断邀请码的唯一性
            String iCode = UUIDUtil.NS() + Maths.random(10, 99);
            Map<String, Object> params = new HashMap<>();
            params.put("invite_code", iCode);
            synchronized (this) {
                boolean flag = true;
                while (flag) {
                    LbbMember member = memberService.getByinviteCode(iCode);
                    if (member != null) {
                        iCode = UUIDUtil.NS() + Maths.random(10, 99);
                        params = new HashMap<>();
                        params.put("invite_code", iCode);
                    } else {
                        flag = false;
                    }
                }
            }

            LbbMember member = new LbbMember();
            member.setBrand("");
            member.setImei("");
            member.setAppStore("");
            member.setAlipay("");
            member.setAlipayName("");
            member.setAppId(app);
            member.setAvatar("");
            member.setBirthday("");
            member.setCategory("True");
            member.setGender(Gender.Unknow.name());
            member.setInviteCode(iCode);

            String inviterId = "";
            if (!TextUtil.isEmpty(inviteCode)) {
                LbbMember parentMember = memberService.getByinviteCode(inviteCode);
                if (parentMember != null) {
                    inviterId = parentMember.getMemberId();
                }
            }

            member.setInviterId(inviterId);
            member.setRequestUri(request.getRequestURI());
            member.setMemberId(UUIDUtil.L());
            member.setNickname(phone);
            member.setPassword(MessageDigestUtil.encryptMD5(password.getBytes()));
            member.setPersonId("");
            member.setPhone(phone);
            member.setRealname("");
            member.setStatus("");
            member.setUnionid("");
            member.setWeixin("");
            member.setWeixinName("");
            memberService.insertMember(member);

            //验证成功删除验证码
            validCodeUtil.cleanCode(phone, RedisLogin.PHONE_REGISTER_CODE, code);
            return Callback.success("200", "注册成功！", "");
        } catch (Exception e) {
            e.printStackTrace();
            return Callback.fail("403", "未知异常", e.getMessage());
        }
    }


    /**
     * 检测用户手机号是否已被注册
     *
     * @param phone
     * @param app
     * @return
     */
    public boolean checkPhone(String phone, String app) {
        // 判断手机号是否注册过
        Map<String, Object> params = new HashMap<String, Object>(1);
        params.put("phone", phone);
        params.put("app_id", app);
        LbbMember member = memberService.getMemberByPhone(phone, app);
        if (member != null) {
            return false;
        }
        return true;
    }


    /**
     * 获取邀请基本信息
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/info", method = RequestMethod.POST)
    @ResponseBody
    public JsonData getInviteInfo(HttpServletRequest request, HttpServletResponse response) {
        RequestHeaders requestHeaders = new RequestHeaders(request);
        try {
            String appid = requestHeaders.getAppid();
            String memberId = requestHeaders.getUserid();
            if (TextUtil.isEmpty(appid, memberId)) {
                return Callback.fail("501", "参数异常", "");
            }


            LbbMember member = getMember(memberId, appid);
            if (member == null) {
                return Callback.fail("502", "用户信息异常", "");
            }

            JSONObject memberJson = new JSONObject();
            memberJson.put("nickname", TextUtil.isEmpty(member.getNickname()) ? member.getPhone() : member.getNickname());
            memberJson.put("imageUrl", member.getAvatar());
            memberJson.put("inviteCode", member.getInviteCode());
            TbMemberInviteStatistics memberInviteStatistics = memberInviteStatisticsService.getByMemberId(memberId);
            if (memberInviteStatistics == null) {
                memberJson.put("valids", 0);
                memberJson.put("numbers", 0);
                memberJson.put("grade", "铜牌师傅");
                memberJson.put("expectMoney", 0.0);
                memberJson.put("totalMoney", 0.0);
            } else {
                memberJson.put("valids", memberInviteStatistics.getNumbers());
                memberJson.put("numbers", memberInviteStatistics.getLastMonthValid() + memberInviteStatistics.getMonthValid());
                memberJson.put("grade", memberInviteStatistics.getGrade());
                memberJson.put("expectMoney", new DecimalFormat("0.00").format(((new BigDecimal(memberInviteMapper.getMemberMoney(memberId)).doubleValue()) * memberInviteStatistics.getRebateProportion().doubleValue() / (100 * 1.000))));
                memberJson.put("totalMoney", new DecimalFormat("0.00").format((memberInviteStatistics.getTotalMoney().doubleValue()) / (100 * 1.000)));
            }

            List<String> noticeList = new ArrayList<>();

            List<Map<String, Object>> mapList = memberInviteStatisticsService.listTop(20);
            if (mapList != null && mapList.size() > 0) {
                for (Map<String, Object> map : mapList) {
                    if (Integer.parseInt(map.get("money").toString()) > 0) {
                        String notice = map.get("phone").toString().replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2") + "已获得佣金奖励<font color='#ff0000'>" + map.get("money") + "</font>元";
                        noticeList.add(notice);
                    }
                }
                if (mapList.size() < 15) {
                    for (int i = 0; i < 10; i++) {
                        String phone = getRandomTel().replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2") + "已获得佣金奖励<font color='#ff0000'>" + String.format("%1.2f", Math.floor(Math.random() * 100 + 20)) + "</font>元";
                        noticeList.add(phone);
                    }
                }
            } else {
                for (int i = 0; i < 15; i++) {
                    String phone = getRandomTel().replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2") + "已获得佣金奖励<font color='#ff0000'>" + String.format("%1.2f", Math.floor(Math.random() * 100 + 20)) + "</font>元";
                    noticeList.add(phone);
                }
            }

            JSONObject data = new JSONObject();
            data.put("member", memberJson);
            data.put("infoList", noticeList);
            return Callback.success("200", "success", data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Callback.fail("403", "网络异常", "");
    }

    private static int getNum(int start, int end) {
        return (int) (Math.random() * (end - start + 1) + start);
    }

    /**
     * 生成一个随机的手机号码
     *
     * @return
     */
    private String getRandomTel() {
        String[] telFirst = "134,135,136,137,138,139,150,151,152,157,158,159,130,131,132,155,156,133,153".split(",");
        int index = getNum(0, telFirst.length - 1);
        String first = telFirst[index];
        String second = String.valueOf(getNum(1, 888) + 10000).substring(1);
        String third = String.valueOf(getNum(1, 9100) + 10000).substring(1);
        return first + second + third;
    }

    /**
     * 获取详细的徒弟信息列表
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/list", method = RequestMethod.POST)
    @ResponseBody
    public JsonData listInviteInfo(HttpServletRequest request, HttpServletResponse response) {
        RequestHeaders requestHeaders = new RequestHeaders(request);
        try {
            String appid = requestHeaders.getAppid();
            String memberId = requestHeaders.getUserid();
            if (TextUtil.isEmpty(appid, memberId)) {
                return Callback.fail("501", "参数异常", "");
            }
            LbbMember member = getMember(memberId, appid);
            if (member == null) {
                return Callback.fail("502", "用户信息异常", "");
            }
            JSONArray data = new JSONArray();
            TbMemberInviteStatistics memberInviteStatistics = memberInviteStatisticsService.getByMemberId(memberId);
            if (memberInviteStatistics != null) {
                List<MemberInviteDetail> memberInviteDetailList = memberInviteMapper.listMemberInvite(memberId, null);

                if (memberInviteDetailList != null && memberInviteDetailList.size() > 0) {
                    for (MemberInviteDetail memberInviteDetail : memberInviteDetailList) {
                        JSONObject json = new JSONObject();
                        json.put("memberId", memberInviteDetail.getMemberId());


                        Map<String, Object> map = memberInviteMapper.selfMoney(memberInviteDetail.getMemberId());

                        json.put("nickname", TextUtil.isEmpty(map.get("nickname")) ? map.get("phone") : map.get("nickname"));

                        double money = ((BigDecimal) map.get("money")).doubleValue();


                            //不加判断，直接每天可提醒一次
                            String date = DateUtil.dateToString(new Date(), "yyyy-MM-dd");
                            json.put("notice", memberInviteMapper.checkNotice(memberId, memberInviteDetail.getMemberId(), date));


                        json.put("expectMoney", new BigDecimal(dictService.selectByKeyName("td_max").getKeyvalue()));
                        json.put("totalMoney", new BigDecimal(memberInviteRebateRecordService.getTotalMoney(memberInviteDetail.getMemberId(),memberId)).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN));
                        json.put("money", new BigDecimal(memberInviteRebateRecordService.getTotalMoney(memberInviteDetail.getMemberId(),memberId)).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN));
                        data.add(json);
                    }
                }
            }


            return Callback.success("200", "success", data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Callback.fail("403", "网络异常", "");
    }


    public LbbMember getMember(String memberId, String appId) {
        try {
            if (!TextUtil.isEmpty(appId, memberId)) {
                Map<String, Object> params = new HashMap<>();
                params.put("app_id", appId);
                params.put("member_id", memberId);
                LbbMember member = memberService.getMemberByMemberId(memberId);
                if (member != null) {
                    return member;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }



    /**
     * 提醒徒弟
     *
     * @param request 用户信息
     * @return 返回结果
     */
    @PostMapping("push")
    @ResponseBody
    public JsonData remind(HttpServletRequest request, @RequestParam(value = "memberid") String memberid) {
        RequestHeaders headers = new RequestHeaders(request);


        try {

            LbbMemberInviteNotice lbbMemberInviteNotice = new LbbMemberInviteNotice();
            lbbMemberInviteNotice.setHasDeleted("False");
            lbbMemberInviteNotice.setInviteId(headers.getUserid());
            lbbMemberInviteNotice.setMemberId(memberid);
            memberInviteNoticeMapper.insertNotice(lbbMemberInviteNotice);


            //最小提现金额
            BigDecimal minCash = cashService.selectMinCash();
            //余额
            BigDecimal balance;
            Integer all = walletService.totalMoney(memberid, headers.getAppid());
            Integer lift = walletService.cashMoney(memberid, headers.getAppid());
            balance = new BigDecimal(all-lift).divide(new BigDecimal(100),BigDecimal.ROUND_DOWN);
            if (balance.compareTo(minCash) < 0) {
                //余额小于最小提现金额
                BigDecimal money = minCash.subtract(balance).setScale(2, BigDecimal.ROUND_DOWN);
                memberNoticeService.addNoticeAndPush("徒儿~", "你还差" + money + "元就可以提现了，加油做任务哦！", memberid, headers);
            } else {
                memberNoticeService.addNoticeAndPush("徒儿~", "你的余额已经足够提现，快去提现吧!", memberid, headers);
            }



        } catch (Exception e) {
            return Callback.fail("201", "提醒失败", null);
        }

        return Callback.success("200", "提醒成功");
    }


}
